home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
SOUND
/
REPLAYER.SPK
/
h
/
replaydriv
next >
Wrap
Text File
|
1998-08-24
|
7KB
|
179 lines
/* replaydriver.h */
/* A veneer to the Replay sound drivers. */
#ifndef lib_replaydriver_H
#define lib_replaydriver_H
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Private declarations for macros later. */
extern void replaydriver_veneer(unsigned r0, unsigned r1, void *driver);
/* A structure covering the driver's header. Don't rely on contents or use
them directly; use the macros below. */
typedef struct replaydriver_driver replaydriver_driver;
struct replaydriver_driver {
unsigned play, stop, feed; /* Entry points. */
int interface_flags; /* Flags about the driver. */
void *buffer[2]; /* Buffer addresses. */
unsigned unsure[3]; /* Not used? */
int timer_int, /* Integer part of current time. */
timer_fract; /* Fractional part of current time. */
};
/* The important Replay control block, used by the sound drivers. The
contents of this are public. */
typedef union replaydriver_control replaydriver_control;
union replaydriver_control {
char mute[64]; /* Called "mute" for hysterical raisins. */
struct {
int flags, /* Allow pausing or muting of sound. */
skip_late_data, /* If set, skip late data. */
replay_rate_int, /* Integer portion of the frequency in Hz. */
replay_rate_fract; /* Fractional part of the frequency * 1<<24. */
char quality, /* Quality to play sound, from 1--4. */
reversed; /* If set, reverse left and right channels. */
} data;
/* Our code also stores some extra state after the 64 bytes, rather than
creating a whole new block. */
struct {
char mute[64];
int next_buffer; /* The next buffer to become empty (0 or 1). */
} extra;
};
/* Information about the sound buffers allocated. Contents private. */
typedef struct replaydriver_buffer replaydriver_buffer;
struct replaydriver_buffer {
size_t single_size; /* Size of each sound buffer. */
void *buffer; /* Address of the beginning of the buffers. */
int dynarea; /* Dynamic area of buffer; -1 for using RMA. */
size_t temp_size; /* Size of temp block allocated (0 for none). */
};
/* Flags */
#define replaydriver_PAUSE (1 << 0)
#define replaydriver_MUTE (1 << 1)
/* Other info */
#define replaydriver_BUFFER_CHECK_WORD 0x1BADDEED
#define replaydriver_DRIVER_PREFIX "<ARMovie$SoundDir>."
/* Initialisation and finalisation. */
/* Loading and freeing drivers. */
replaydriver_driver *replaydriver_load(const char *filename);
void replaydriver_destroy(replaydriver_driver *driver);
/* Loading and freeing control blocks. */
replaydriver_control *replaydriver_control_create(void);
void replaydriver_control_destroy(replaydriver_control *control);
/* Methods for fiddling with the driver's header and using entry points. */
/* Sound driver entry points. */
/* For public use. */
#define replaydriver_play(driver, control) \
replaydriver_play_entry(driver, control, 2)
void replaydriver_stop(replaydriver_driver *driver,
replaydriver_control *control);
/* For internal use. */
#define replaydriver_play_entry(driver, control, param) \
if((driver) && (control)) \
replaydriver_veneer((param), (unsigned) (control), \
(void *) &(driver)->play)
/* Performing the sound timing check. */
/* The state type may be initialised to zero, and then will be true only
when a sound check is in progress. */
typedef int replaydriver_timecheck_state;
void replaydriver_timecheck_start(replaydriver_driver *driver,
replaydriver_control *control, replaydriver_timecheck_state *state);
void replaydriver_timecheck_finish(replaydriver_driver *driver,
replaydriver_control *control, replaydriver_timecheck_state *state);
void replaydriver_timecheck_abort(replaydriver_driver *driver,
replaydriver_control *control, replaydriver_timecheck_state *state);
/* Read the driver's flags. */
#define replaydriver_NO_SOUND_CHECK (1 << 0)
#define replaydriver_QUALITY_EXPENSIVE (1 << 1)
#define replaydriver_get_flags(driver) \
((driver) ? ((const int) (driver)->interface_flags) : 0)
/* Set sound rate (in Hz, floating point) in control block. */
#define replaydriver_set_rate(control, rate) \
((control) ? \
((control)->data.replay_rate_int = (int) (rate), \
(control)->data.replay_rate_fract = \
(int) (((rate) - (int) (rate)) * (1<<24))) : 0, \
(void) 0)
/* Set or read buffer locations. */
/* There are 2 sound buffers, so the number can be 0 or 1. */
#define replaydriver_set_buffer(driver, buffer_no, block) \
((driver) ? (driver)->buffer[buffer_no] = (block) : 0)
#define replaydriver_get_buffer(driver, buffer_no) \
((void * const) (driver)->buffer[buffer_no])
/* Returns a pointer to the buffer empty flag. */
#define replaydriver_buffer_empty(driver, buffer_no) \
(&((int *) replaydriver_get_buffer((driver), (buffer_no)))[1])
/* Sound buffer allocation. */
replaydriver_buffer *replaydriver_buffer_create(int single_size,
replaydriver_driver *driver);
void replaydriver_buffer_destroy(replaydriver_buffer *buffer);
/* Checking buffer integrity (uses check word at end). Non-zero for fail. */
#define replaydriver_buffer_check(buffer_obj) \
((*(int *) ((char *) (buffer_obj)->buffer + \
(buffer_obj)->single_size) \
!= replaydriver_BUFFER_CHECK_WORD) || \
(*(int *) ((char *) (buffer_obj)->buffer + \
((buffer_obj)->single_size * 2) + 4) \
!= replaydriver_BUFFER_CHECK_WORD))
/* Allocation of temporary space. */
void *replaydriver_temp_alloc(replaydriver_buffer *buffer, size_t size);
void replaydriver_temp_free(replaydriver_buffer *buffer, void *block);
/* Feeding data, and checking whether a buffer is empty. */
#define replaydriver_is_hungry(driver) \
(((int *) replaydriver_get_buffer((driver), 0))[1] || \
((int *) replaydriver_get_buffer((driver), 1))[1])
#define replaydriver_buffers_empty(driver) \
(((int *) replaydriver_get_buffer((driver), 0))[1] && \
((int *) replaydriver_get_buffer((driver), 1))[1])
void replaydriver_feed(replaydriver_driver *driver,
replaydriver_control *control, void *data, size_t size);
/* Get a poll word. */
#define replaydriver_get_poll_word(driver, control) \
((const int *) replaydriver_buffer_empty((driver), \
(control)->extra.next_buffer))
/* Reading time info. */
/* These return the integer and fractional parts of the driver's record. */
#define replaydriver_get_time_int(driver) \
((const int) (driver)->timer_int)
#define replaydriver_get_time_fract(driver) \
((const int) (driver)->timer_fract)
/* This returns the time in centiseconds given driver and control blocks. */
#define replaydriver_get_time(driver, control) \
((int) ((double) replaydriver_get_time_int((driver)) * 100 / \
((double) (control)->data.replay_rate_int + \
(double) (control)->data.replay_rate_fract / (1<<24))))
#ifdef __cplusplus
}
#endif
#endif